function diff(oldTree, newTree){
    let patches = {} //补丁
    walk(oldTree, newTree, 0, patches)
    return patches
}
const ATTRS = 'ATTRS'
const TEXT = 'TEXT'
const REMOVE = 'REMOVE'
const REPLACE = 'REPLACE'
let Index = 0
function walk(oldNode, newNode, index, patches){
    let currentPatch = []
    if(!newNode){
        currentPatch.push({type: REMOVE, index})
    }else if(isText(oldNode) && isText(newNode)){
        //比较文本
        if(oldNode !== newNode){
            currentPatch.push({type: TEXT, text: newNode})
        }
    }else if(oldNode.type === newNode.type){
        //比较属性
        let attrs = diffAttr(oldNode.props, newNode.props)
        if(Object.keys(attrs).length ){
            currentPatch.push({type: ATTRS, attrs})
        }
        //如果有孩子节点，处理孩子
        diffChildren(oldNode.children, newNode.children, patches)
    }else{
        currentPatch.push({type: REPLACE, newNode})
    }
    if(currentPatch.length){
        patches[index] = currentPatch
    }
}

//比较属性
function diffAttr(oldAttrs, newAttrs){
    let patch = {}
    //更新或删除属性
    for(let key in oldAttrs){
        if(oldAttrs[key] !== newAttrs[key]){
            patch[key] = newAttrs[key]
        }
    }
    //添加新属性
    for(let key in newAttrs){
        if(!oldAttrs.hasOwnProperty(key)){
            patch[key] = newAttrs[key]
        }
    }
    return patch
}

//处理孩子
function diffChildren(oldChildren, newChildren, patches){
    oldChildren.forEach((child, idx) => {
        walk(child, newChildren[idx], ++Index, patches)
    })
}

//判断是否是文本
function isText(node){
    return Object.prototype.toString.call(node) === '[object String]'
}